package com.allwees.bs.module.scm.service.impl;

import com.allwees.bs.core.modelbase.function.FunctionFill;
import com.allwees.bs.core.modelbase.function.FunctionValidatable;
import com.allwees.bs.module.base.service.impl.BoServiceImpl;
import com.allwees.bs.module.scm.dao.ScmShippingOrderSkuDao;
import com.allwees.bs.module.scm.entity.ScmShippingOrderSku;
import com.allwees.bs.module.scm.req.internal.EnteredWarehouseSkuReq;
import com.allwees.bs.module.scm.service.ScmShippingOrderSkuService;
import com.allwees.core.common.constant.EStatus;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * scm 物流发货单
 *
 * @author mouhn
 * @since 2020-1-3 17:39
 */
@Service
public class ScmShippingOrderSkuServiceImpl extends BoServiceImpl<ScmShippingOrderSkuDao, ScmShippingOrderSku> implements ScmShippingOrderSkuService {

    @Autowired
    private UserService userService;

    @Autowired
    private ScmShippingOrderSkuDao shippingOrderSkuDao;

    @Override
    public List<ScmShippingOrderSku> findOrderSkus(String shippingOrderUuid) {
        return shippingOrderSkuDao.findByShippingOrderUuid(shippingOrderUuid);
    }

    @Override
    public ScmShippingOrderSku enteredWarehouse(EnteredWarehouseSkuReq enteredWarehouseSku, String operatorUuid) {
        UserDto userDto = userService.findByUuid(operatorUuid);

        return _updateStatus(enteredWarehouseSku.getShippingOrderSkuUuid(), o -> {
            o.assertStatus(EStatus.SCM_WAIT_ENTER);
        }, o -> {
            o.setEStatus(EStatus.SCM_ENTERED);
            o.setEnteredWarehouseUserUuid(operatorUuid)
                    .setEnteredWarehouseUserName(userDto.getUsername())
                    .setShelfUuid(enteredWarehouseSku.getShelfUuid())
                    .setSlotUuid(enteredWarehouseSku.getSlotUuid());
        });
    }

    @Override
    public ScmShippingOrderSku refund(String uuid, String reason, String operatorUuid) {
        UserDto userDto = userService.findByUuid(operatorUuid);

        return _updateStatus(uuid, o -> {
            o.assertStatus(EStatus.SCM_WAIT_ENTER);
        }, o -> {
            o.setEStatus(EStatus.REFUND);
            o.setRefundReason(reason)
                    .setRefundUserUuid(operatorUuid)
                    .setRefundUserName(userDto.getUsername());
        });
    }

    @Override
    public void print(String uuid) {

    }

    @Override
    public void refundReason(String uuid) {

    }

    private ScmShippingOrderSku _updateStatus(String uuid, FunctionValidatable<ScmShippingOrderSku> validatable, FunctionFill<ScmShippingOrderSku> fill) {

        ScmShippingOrderSku shippingOrderSku = checkByUuid(uuid);
        if (validatable != null) {
            validatable.validate(shippingOrderSku);
        }

        ScmShippingOrderSku update = new ScmShippingOrderSku();
        update.setUuid(shippingOrderSku.getUuid());

        if (fill != null) {
            fill.fill(update);
        }
        updateByUuid(shippingOrderSku);
        return shippingOrderSku;
    }

    @Override
    public boolean allEnterWarehouse(String pickOrderSkuUuid) {
        if(StringUtils.isBlank(pickOrderSkuUuid)){
            return false;
        }
        return allCountEqStatusCount(pickOrderSkuUuid, EStatus.SCM_ENTERED);
    }

    @Override
    public boolean allRefund(String pickOrderSkuUuid) {
        return allCountEqStatusCount(pickOrderSkuUuid, EStatus.REFUND);
    }

    private boolean allCountEqStatusCount(String pickOrderSkuUuid, EStatus status) {

        Integer allCount = shippingOrderSkuDao.findCountByShippingOrderUuid(pickOrderSkuUuid);
        Integer statusCount = shippingOrderSkuDao.findCountByShippingOrderUuid(pickOrderSkuUuid, status);

        return !allCount.equals(statusCount);
    }
}
